#include #include #include using namespace std; struct BitmapFileHeader { char bfType[2]; unsigned int bfSize; unsigned short bfReserved1; unsigned short bfReserved2; unsigned int bfOffBits; void read(ifstream& fin); void write(ofstream& fout); void display(); }; void BitmapFileHeader::read(ifstream& fin) { if(!fin.fail()) { fin.read(bfType ,2); fin.read((char*)&(bfSize),4); fin.read((char*)&(bfReserved1),2); fin.read((char*)&(bfReserved2),2); fin.read((char*)&(bfOffBits),4); } } void BitmapFileHeader::write(ofstream& fout) { if(!fout.fail()) { fout.write(bfType ,2); fout.write((char*)&(bfSize),4); fout.write((char*)&(bfReserved1),2); fout.write((char*)&(bfReserved2),2); fout.write((char*)&(bfOffBits),4); } } void BitmapFileHeader::display() { cout << "Bitmap File Header" << endl; cout << "bfType = " << bfType[0] << bfType[1] << endl; cout << "bfSize = " << bfSize << endl; cout << "bfReserved1 = " << bfReserved1 << endl; cout << "bfReserved2 = " << bfReserved2 << endl; cout << "bfOffBits = " << bfOffBits << endl << endl; } struct BitmapInfoHeader { unsigned int biSize; unsigned int biWidth; unsigned int biHeight; unsigned short biPlanes; unsigned short biBitCount; unsigned int biCompression; unsigned int biSizeImage; unsigned int biXPelsPerMeter; unsigned int biYPelsPerMeter; unsigned int biCirUsed; unsigned int biCirImportant; void read(ifstream& fin); void write(ofstream& fout); void display(); }; void BitmapInfoHeader::read(ifstream& fin) { if(!fin.fail()) { fin.read((char*)&(biSize),4); fin.read((char*)&(biWidth),4); fin.read((char*)&(biHeight),4); fin.read((char*)&(biPlanes),2); fin.read((char*)&(biBitCount),2); fin.read((char*)&(biCompression),4); fin.read((char*)&(biSizeImage),4); fin.read((char*)&(biXPelsPerMeter),4); fin.read((char*)&(biYPelsPerMeter),4); fin.read((char*)&(biCirUsed),4); fin.read((char*)&(biCirImportant),4); } } void BitmapInfoHeader::write(ofstream& fout) { if(!fout.fail()) { fout.write((char*)&(biSize),4); fout.write((char*)&(biWidth),4); fout.write((char*)&(biHeight),4); fout.write((char*)&(biPlanes),2); fout.write((char*)&(biBitCount),2); fout.write((char*)&(biCompression),4); fout.write((char*)&(biSizeImage),4); fout.write((char*)&(biXPelsPerMeter),4); fout.write((char*)&(biYPelsPerMeter),4); fout.write((char*)&(biCirUsed),4); fout.write((char*)&(biCirImportant),4); } } void BitmapInfoHeader::display() { cout << "Bitmap Info Header" << endl; cout << "biSize = " << biSize << endl; cout << "biWidth = " << biWidth << endl; cout << "biHeight = " << biHeight << endl; cout << "biPlanes = " << biPlanes << endl; cout << "biBitCount = " << biBitCount << endl; cout << "biCompression = " << biCompression << endl; cout << "biSizeImage = " << biSizeImage << endl; cout << "biXPelsPerMeter = " << biXPelsPerMeter << endl; cout << "biYPelsPerMeter = " << biYPelsPerMeter << endl; cout << "biCirUsed = " << biCirUsed << endl; cout << "biCirImportant = " << biCirImportant << endl << endl; } struct Pixel { unsigned char blue; unsigned char green; unsigned char red; }; struct Image { BitmapFileHeader fileHeader; BitmapInfoHeader infoHeader; Pixel* pixels; void getPixels(ifstream& fin); void writePixels(ofstream& fout); void displayPixels(); }; void Image::getPixels(ifstream& fin) { if(!fin.fail()) { pixels = new Pixel[infoHeader.biHeight*infoHeader.biWidth]; int bytesRead = 0; for(unsigned int i = 0; i<(infoHeader.biHeight*infoHeader.biWidth); i++) { fin.read((char*)(&pixels[i].blue),1); fin.read((char*)(&pixels[i].green),1); fin.read((char*)(&pixels[i].red),1); bytesRead += 3; if(bytesRead == infoHeader.biWidth*3) { int garbageBytes = (4 - (bytesRead%4)); if(garbageBytes > 0 && garbageBytes < 4) { fin.seekg(garbageBytes,ios::cur); bytesRead = 0; } } } } } void Image::writePixels(ofstream& fout) { int bytesRead = 0; for(unsigned int i = 0; i<(infoHeader.biHeight*infoHeader.biWidth); i++) { fout.write((char*)(&pixels[i].blue),1); fout.write((char*)(&pixels[i].green),1); fout.write((char*)(&pixels[i].red),1); bytesRead += 3; if(bytesRead == infoHeader.biWidth*3) { int garbageBytes = (4 - (bytesRead%4)); unsigned char garbage[3] = {0}; if(garbageBytes > 0 && garbageBytes < 4) { fout.write((char*)garbage,garbageBytes); bytesRead = 0; } } } } void Image::displayPixels() { for(unsigned int i = 0; i offsetOfRow; column--) { image.pixels[column] = image.pixels[column - 1]; } image.pixels[offsetOfRow] = tempPixel; } offsetOfRow += image.infoHeader.biWidth; } } void main() { string filename; cout << "Bitmap file name?"; getline(cin,filename); cout << endl; ifstream fin(filename, ios::binary); Image image; image.fileHeader.read(fin); image.infoHeader.read(fin); image.getPixels(fin); fin.close(); image.fileHeader.display(); image.infoHeader.display(); //image.displayPixels(); skewImage(image); ofstream fout("out.bmp", ios::binary); image.fileHeader.write(fout); image.infoHeader.write(fout); image.writePixels(fout); delete []image.pixels; }